package cn.spream.jstudy.crypto;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * DES加密
 * <p/>
 * Created with IntelliJ IDEA.
 * User: sjx
 * Date: 14-11-12
 * Time: 下午2:41
 * To change this template use File | Settings | File Templates.
 */
public class DESCrypto {

    private final static String CHARSET = "UTF-8";
    private final static String ALGORITHM = "TripleDES";

    /**
     * 生成加密KEY
     *
     * @param key 密钥
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static Key toKey(String key) throws IOException {
        return new SecretKeySpec(new BASE64Decoder().decodeBuffer(key), ALGORITHM);
    }

    /**
     * 加密
     *
     * @param key
     * @param str
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchPaddingException
     * @throws IllegalBlockSizeException
     * @throws UnsupportedEncodingException
     */
    public static String encrypt(String key, String str) throws Exception {
        return encrypt(toKey(key), str);
    }

    /**
     * 加密
     *
     * @param key
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static String encrypt(Key key, String str) throws Exception {
        return new BASE64Encoder().encode(encrypt(key, str.getBytes(CHARSET)));
    }

    /**
     * 加密
     *
     * @param key
     * @param bytes
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    private static byte[] encrypt(Key key, byte[] bytes) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key, new SecureRandom());
        return cipher.doFinal(bytes);
    }

    /**
     * 解密
     *
     * @param key
     * @param str
     * @return
     * @throws IOException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static String decrypt(String key, String str) throws Exception {
        return decrypt(toKey(key), str);
    }

    /**
     * 解密
     *
     * @param key
     * @param str
     * @return
     * @throws IOException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static String decrypt(Key key, String str) throws Exception {
        return new String(decrypt(key, new BASE64Decoder().decodeBuffer(str)), CHARSET);
    }

    /**
     * 解密
     *
     * @param key
     * @param bytes
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    private static byte[] decrypt(Key key, byte[] bytes) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key, new SecureRandom());
        return cipher.doFinal(bytes);
    }

}
